package com.eliauk.democommon.utils.file;


import com.eliauk.democommon.utils.file.FileSizeUnit;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.io.IOException;
import java.io.InputStream;
import java.util.Set;

public class MyFileUtil {

    /**
     * 检查上传文件的大小是否小于等于指定的最大大小。
     * @param file 上传的文件
     * @param maxSize 允许的最大文件大小（单位：兆字节）
     * @return 如果文件大小符合要求，返回 true；否则返回 false。
     */
    public static Boolean checkSize(MultipartFile file, long maxSize) {
        if (file==null||file.isEmpty()||file.getSize()==0)
            return false;
        return file.getSize() <= maxSize;
    }

    /**
     * 检查上传文件的大小是否小于等于指定的最大大小。
     *
     * @param file      上传的文件
     * @param maxSize   允许的最大文件大小
     * @param unit      文件大小的单位
     * @return 如果文件大小符合要求，返回 true；否则返回 false。
     */
    public static Boolean checkSize(MultipartFile file, int maxSize, FileSizeUnit unit) {
        long maxSizeInBytes = unit.toBytes(maxSize);
        if (file==null||file.isEmpty()||file.getSize()==0)
            return false;
        return file.getSize() <= maxSizeInBytes;
    }

    /**
     * 检查上传文件的格式是否符合允许的文件类型。
     *
     * @param file           上传的文件
     * @param allowTypeSet   允许的文件类型集合
     * @return 如果文件格式符合要求，返回 true；否则返回 false。
     * @throws IOException 如果发生IO错误
     */
    public static Boolean checkFormat(MultipartFile file, Set<String> allowTypeSet) throws IOException {
        //文件名为空
        String fileName = file.getOriginalFilename();
        if (fileName == null) {
            return false;
        }

        //文件后缀不支持
        String suffix = getFileSuffix(fileName);
        if (!allowTypeSet.contains(suffix)){
            return false;
        }

        //图像文件无法打开或解析，例如损坏的图像文件。
        //图像文件格式不受支持或不是真正的图像文件(比如说一个java文件改后缀名改成png)
        try (InputStream inputStream = file.getInputStream()) {
            if (!isImage(inputStream)) {
                return false;
            }
        }

        return true;
    }


    /**
     * 提取文件名中的后缀。
     *
     * @param fileName 上传文件的原始文件名
     * @return 文件的后缀（小写字母）
     */
    private static String getFileSuffix(String fileName) {
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex == -1 || lastDotIndex == fileName.length() - 1) {
            return ""; // 没有文件扩展名
        }
        return fileName.substring(lastDotIndex + 1).toLowerCase();
    }

    /**
     * 判断输入流是否包含有效的图像。
     *
     * @param inputStream 文件输入流
     * @return 如果是有效的图像，返回 true；否则返回 false。
     */
    private static boolean isImage(InputStream inputStream) {
        try {
            // 使用 ImageIO 来判断文件是否为有效的图像 但是ImageIO许久未更新，已经读不出Webp （没有这一类型的ImageReader） 但是我们可以添加一个 webp-imageio 依赖
            return ImageIO.read(inputStream) != null;
        } catch (IOException e) {
            // 处理异常，例如损坏的图像文件
            return false;
        }
    }
    


}
